<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="d8P8L" id="d8P8L"><span data-lake-id="ub924646a" id="ub924646a">典型回答</span></h1>
  <p data-lake-id="u62d0f6f5" id="u62d0f6f5"><br></p>
  <p data-lake-id="u18d4e4a9" id="u18d4e4a9"><span data-lake-id="u17a474c2" id="u17a474c2">OutOfMemory 是内存溢出错误，他通常发生在程序试图分配内存时，但是超出可用内存限制。这可能是因为程序使用了太多内存，或者由于内存泄漏而导致内存不断累积。</span></p>
  <p data-lake-id="u3d318b55" id="u3d318b55"><span data-lake-id="u18d7a5f0" id="u18d7a5f0">​</span><br></p>
  <p data-lake-id="ub2d8bd36" id="ub2d8bd36"><span data-lake-id="u1122a011" id="u1122a011">StackOverflow 是栈溢出错误，他通常发生在程序的调用栈变得过深时，如递归调用。每次函数调用都会在栈上分配一些内存，当递归调用或者函数调用层次过深时，栈空间会被耗尽，从而导致StackOverflowError。</span></p>
  <p data-lake-id="u778e5101" id="u778e5101"><br></p>
  <p data-lake-id="u256f5ebe" id="u256f5ebe"><span data-lake-id="ucdf91654" id="ucdf91654">​</span><br></p>
  <p data-lake-id="u190183c7" id="u190183c7"><span data-lake-id="u9355ce20" id="u9355ce20">OutOfMemory一般发生在Java的堆内存上，StackOverflow一般发生在Java的栈内存中。但是也不绝对，在栈上也可能发生OutOfMemory。</span></p>
  <h1 data-lake-id="i8mQO" id="i8mQO"><span data-lake-id="uaefe716e" id="uaefe716e">扩展知识</span></h1>
  <p data-lake-id="u5b25a792" id="u5b25a792"><br></p>
  <h2 data-lake-id="u6TtJ" id="u6TtJ"><span data-lake-id="u95813734" id="u95813734">OutOfMemory</span></h2>
  <p data-lake-id="uad6c53ef" id="uad6c53ef"><span data-lake-id="uadb2d50d" id="uadb2d50d">​</span><br></p>
  <p data-lake-id="u949ab321" id="u949ab321"><span data-lake-id="u5a3dbfa8" id="u5a3dbfa8">OutOfMemory在具体报错上还有以下几种情况：</span></p>
  <p data-lake-id="u56563ac4" id="u56563ac4"><span data-lake-id="u6b09726c" id="u6b09726c">​</span><br></p>
  <ol list="u2582cf2f">
   <li fid="ub76b430e" data-lake-id="uf0f4baaa" id="uf0f4baaa"><span data-lake-id="u2ccade45" id="u2ccade45">Java Heap Space</span><span data-lake-id="ub7cc29ff" id="ub7cc29ff">：这是最常见的OutOfMemoryError。它发生在Java堆内存不足，通常由程序中创建的对象过多或者单个对象太大引起。这种错误可能导致Java应用程序崩溃。</span></li>
   <li fid="ub76b430e" data-lake-id="uf1fcbe46" id="uf1fcbe46"><span data-lake-id="u68a8ddcd" id="u68a8ddcd">PermGen Space（在Java 7之前）或 Metaspace（在Java 8及更高版本）：这种错误发生在永久代（Java 7之前）或元空间（Java 8及更高版本）不足。通常由于加载过多的类或创建过多的动态代理类等原因引起。</span></li>
   <li fid="ub76b430e" data-lake-id="uc9049a71" id="uc9049a71"><span data-lake-id="ue9194d16" id="ue9194d16">Native Heap</span><span data-lake-id="u43846e08" id="u43846e08">：这种错误发生在本机堆内存不足。Java虚拟机使用本机代码（native code）来执行某些操作，如本机方法，这些操作可能会占用本机堆内存。</span></li>
   <li fid="ub76b430e" data-lake-id="u02ef28d6" id="u02ef28d6"><span data-lake-id="u831f12d4" id="u831f12d4">Direct Memory</span><span data-lake-id="u9ba8cb68" id="u9ba8cb68">：这种错误发生在程序使用NIO（New I/O）库或直接内存缓冲区时，由于分配了过多的直接内存而耗尽。</span></li>
   <li fid="ub76b430e" data-lake-id="ue650432a" id="ue650432a"><span data-lake-id="ud784308b" id="ud784308b">GC Overhead Limit Exceeded</span><span data-lake-id="u7afc6911" id="u7afc6911">：这个错误发生在垃圾收集器花费了太多时间进行垃圾回收，而没有足够的内存被释放。这通常是由于内存不足以满足垃圾收集需求而引起的。</span></li>
   <li fid="ub76b430e" data-lake-id="u2bdfd09f" id="u2bdfd09f"><span data-lake-id="ue078dd86" id="ue078dd86">Requested array size exceeds VM limit</span><span data-lake-id="uebf8bbf7" id="uebf8bbf7">：这个错误发生在试图创建一个太大的数组，超过了虚拟机的限制。</span></li>
   <li fid="ub76b430e" data-lake-id="u3b36c71c" id="u3b36c71c"><span data-lake-id="ue6184aff" id="ue6184aff">Unable to create new native thread：这个错误发生在虚拟机无法创建更多的本机线程，通常由于操作系统限制引起。</span></li>
  </ol>
  <p data-lake-id="udb0dc9f0" id="udb0dc9f0"><span data-lake-id="uc929e910" id="uc929e910">​</span><br></p>
  <h2 data-lake-id="HgitJ" id="HgitJ"><span data-lake-id="uadc47ac6" id="uadc47ac6">栈上OOM</span></h2>
  <p data-lake-id="u642b2eb3" id="u642b2eb3"><br></p>
  <p data-lake-id="u4d6b719b" id="u4d6b719b"><span data-lake-id="u68038a1d" id="u68038a1d">在《Java虚拟机规范》规定了：</span><strong><span data-lake-id="ubaa20ac0" id="ubaa20ac0">如果虚拟机的栈内存允许动态扩展，当扩展栈容量无法申请到足够的内存时，将抛出OutOfMemoryError异常。</span></strong></p>
  <p data-lake-id="uf8509ff9" id="uf8509ff9"><span data-lake-id="ua5d7526a" id="ua5d7526a">​</span><br></p>
  <p data-lake-id="u12ca1f35" id="u12ca1f35"><span data-lake-id="u31f13e76" id="u31f13e76">在某些编程语言和运行时环境中，栈内存允许动态扩展，而不会固定在一个特定的大小。这种情况下，栈内存可以动态增加，以适应程序的需要。然而，这种实现在Java中并不常见，如我们常用的Hotspot虚拟机种，栈内存是有限且固定的，不能动态扩展。</span></p>
  <p data-lake-id="ua461a0ba" id="ua461a0ba"><span data-lake-id="u6e79501d" id="u6e79501d">​</span><br></p>
  <p data-lake-id="u924020c0" id="u924020c0"><span data-lake-id="ua645024a" id="ua645024a">所以，在HotSpot虚拟机中是不会出现因为栈空间不足而抛出OutOfMemoryError异常的情况的，只会发生StackOverflow。</span></p>
  <p data-lake-id="uf0611ea9" id="uf0611ea9"><span data-lake-id="u5e135d85" id="u5e135d85">​</span><br></p>
  <p data-lake-id="u939912c2" id="u939912c2"><span data-lake-id="u44db105e" id="u44db105e">​</span><br></p>
  <p data-lake-id="u48c6def6" id="u48c6def6"><span data-lake-id="uf4d7c9d2" id="uf4d7c9d2">​</span><br></p>
 </body>
</html>